题意
给出一个串S,和一个串T.
要求 从S串中取一个子串,后面接上T串的一个前缀 组成一个结果串,(要求S串的部分比T串的部分长)
其中,S串贡献的部分 可以分成两部分,S1+S2;
前面的S1 是T部分的反转;
S2 就只能是回文串,因为S串的部分必须比T的多,所以S2长度必须大于等于1
然后我们可以分成两部分,首先先把S中的所有回文串求出,可以用(回文树/马拉车/字符串哈希)
对于每一个回文串,它的左边半径部分都可以作为S1的右端点,除了中心,而且边缘也可以吃到一个
比如 CABABA 其中 回文串中心是第二个A,S1的右端点可以是CAB 注意C也可以的哦
然后找出这个端点剩下的就是求S1和T的lcp的长度了,根据题意每一个长度都一个贡献一个符合要求的答案
针对这个问题 我们可以把S 反转 和T用EXKMP 求lcp (也可以用后缀数组/字符串哈希/exkmp/后缀自动机)
所以 这题的解法大概有(3×3=9 或者3×4=12)种。
做法1 :马拉车+EXKMP
1 | ///感谢Grunt 大佬的细心讲解 |
做法2. 回文自动机+EXKMP
题意:给S串与T串。S[i..j]+T[1..k]为回文串,且|S[i..j]|>|T[1..k]|,求(i,j,k)个数。
将S[i..j]分为两个部分,S[i..p]为T[1..k]的反转,S[p+1..j]为回文串。
由于|S[i..j]|>|T[1..k]|,所以S[p+1..j]必须不为空。
枚举回文串的起始点p+1,那么我们要求的是:
1.由于S[i..p]为T[1..k]的反转,我们只要求有多少个(i,k)。这个部分是exkmp的基础。
将S反转,跟T跑exkmp,求出ex[],再把ex[]反过来即可。
2.S[p+1..j]为回文串,我们只要求有多少个j,即求的是以p+1为起点的回文串个数cnt[]。
那么只要把S串倒着插入回文自动机,cnt[i]=插入第i个字符后,fail树的深度。
最后枚举回文串起点p+1,算出ex[p]*cnt[p+1],求和即为答案。
1 |
|
做法3.后缀数组+回文自动机(498ms)
1 |
|
感谢Grunt 大佬的细心讲解!!
///感谢Grunt 大佬的细心讲解
!(Mediocre String Problem/a.jpg)
毅种循环~
!(Mediocre String Problem/b.jpg)